home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / share / apps / dcopidlng / kdocParseDoc.pm < prev    next >
Text File  |  2005-09-10  |  8KB  |  420 lines

  1. package kdocParseDoc;
  2.  
  3. use Ast;
  4. use strict;
  5.  
  6. use vars qw/ $buffer $docNode %extraprops $currentProp $propType /;
  7.  
  8. =head1 kdocParseDoc
  9.  
  10.     Routines for parsing of javadoc comments.
  11.  
  12. =head2 newDocComment
  13.  
  14.     Parameters: begin (starting line of declaration)
  15.  
  16.     Reads a doc comment to the end and creates a new doc node.
  17.  
  18.     Read a line
  19.     check if it changes the current context
  20.         yes
  21.             flush old context
  22.             check if it is a non-text tag 
  23.                         (ie internal/deprecated etc)
  24.                 yes
  25.                     reset context to text
  26.                     set associated property
  27.                 no
  28.                     set the new context
  29.                     assign text to new buffer
  30.         no    add to text buffer
  31.             continue
  32.     at end
  33.         flush anything pending.
  34.  
  35. =cut
  36.  
  37. sub newDocComment
  38. {
  39.     my( $text ) = @_;
  40.     return undef unless $text =~ m#/\*\*+#;
  41.  
  42.     setType( "DocText", 2 );
  43.     $text =~ m#/\*#; # need to do the match again, otherwise /***/ doesn't parse
  44.     ### TODO update this method from kdoc
  45.     $buffer = $'; # everything after the first \*
  46.     $docNode = undef;
  47.     %extraprops = ();    # used for textprops when flushing.
  48.     my $finished = 0;
  49.     my $inbounded = 0;
  50.  
  51.     if ( $buffer =~ m#\*/# ) {
  52.         $buffer = $`;
  53.         $finished = 1;
  54.     }
  55.  
  56. PARSELOOP:
  57.     while ( defined $text && !$finished ) {
  58.         # read text and remove leading junk
  59.         $text = main::readSourceLine();
  60.         next if !defined $text;
  61.         $text =~ s#^\s*\*(?!\/)##;
  62.  
  63. #        if ( $text =~ /^\s*<\/pre>/i ) {
  64. #            flushProp();
  65. #            $inbounded = 0;
  66. #        }
  67.         if( $inbounded ) {
  68.             if ( $text =~ m#\*/# ) {
  69.                 $finished = 1;
  70.                 $text = $`;
  71.             }
  72.             $buffer .= $text;
  73.             next PARSELOOP;
  74.         }
  75. #        elsif ( $text =~ /^\s*<pre>/i ) {
  76. #            textProp( "Pre" );
  77. #            $inbounded = 1;
  78. #        }
  79.         elsif ( $text =~ /^\s*$/ ) {
  80.             textProp( "ParaBreak", "\n" );
  81.         }
  82.         elsif ( $text =~ /^\s*\@internal\s*/ ) {
  83.             codeProp( "Internal", 1 );
  84.         }
  85.         elsif ( $text =~ /^\s*\@deprecated\s*/ ) {
  86.             codeProp( "Deprecated", 1 );
  87.         }
  88.         elsif ( $text =~ /^\s*\@reimplemented\s*/ ) {
  89.             codeProp( "Reimplemented", 1 );
  90.         }
  91.         elsif ( $text =~ /^\s*\@group\s*/ ) {
  92.             # logical group tag in which this node belongs
  93.             # multiples allowed
  94.  
  95.             my $groups = $';
  96.             $groups =~ s/^\s*(.*?)\s*$/$1/;
  97.  
  98.             if ( $groups ne "" ) {
  99.                 foreach my $g ( split( /[^_\w]+/, $groups) ) {
  100.  
  101.                     codeProp( "InGroup", $g );
  102.                 }
  103.             }
  104.         }
  105.         elsif ( $text =~ /^\s*\@defgroup\s+(\w+)\s*/ ) {
  106.             # parse group tag and description
  107.             my $grptag = $1;
  108.             my $grpdesc = $' eq "" ? $grptag : $';
  109.             
  110.             # create group node
  111.             my $grpnode = Ast::New( $grptag );
  112.             $grpnode->AddProp( "Desc", $grpdesc );
  113.             $grpnode->AddProp( "NodeType", "GroupDef" );
  114.  
  115.             # attach
  116.             codeProp( "Groups", $grpnode );
  117.         }
  118.         elsif ( $text =~ /^\s*\@see\s*/ ) {
  119.             docListProp( "See" );
  120.         }
  121.         elsif( $text =~ /^\s*\@short\s*/ ) {
  122.             docProp( "ClassShort" );
  123.         }
  124.         elsif( $text =~ /^\s*\@author\s*/ ) {
  125.             docProp( "Author" );
  126.  
  127.         }
  128.         elsif( $text =~ /^\s*\@version\s*/ ) {
  129.             docProp( "Version" );
  130.         }
  131.         elsif( $text =~ /^\s*\@id\s*/ ) {
  132.  
  133.             docProp( "Id" );
  134.         }
  135.         elsif( $text =~ /^\s*\@since\s*/ ) {
  136.             docProp( "Since" );
  137.         }
  138.         elsif( $text =~ /^\s*\@returns?\s*/ ) {
  139.             docProp( "Returns" );
  140.         }
  141.         elsif( $text =~ /^\s*\@(?:throws|exception|raises)\s*/ ) {
  142.             docListProp( "Throws" );
  143.         }
  144.         elsif( $text =~ /^\s*\@image\s+([^\s]+)\s*/ ) {
  145.             textProp( "Image" );
  146.             $extraprops{ "Path" } = $1;
  147.         }
  148.         elsif( $text =~ /^\s*\@param\s+(\w+)\s*/ ) {
  149.             textProp( "Param" );
  150.             $extraprops{ "Name" } = $1;
  151.         }
  152.         elsif( $text =~ /^\s*\@sect\s+/ ) {
  153.  
  154.             textProp( "DocSection" );
  155.         }
  156.         elsif( $text =~ /^\s*\@li\s+/ ) {
  157.  
  158.             textProp( "ListItem" );
  159.         }
  160.         elsif ( $text =~ /^\s*\@libdoc\s+/ ) {
  161.             # Defines the text for the entire library
  162.             docProp( "LibDoc" );
  163.         }
  164.         else {
  165.             if ( $text =~ m#\*/# ) {
  166.                 $finished = 1;
  167.                 $text = $`;
  168.             }
  169.             $buffer .= $text;
  170.         }
  171.     }
  172.  
  173.     flushProp();
  174.  
  175.  
  176.     return undef if !defined $docNode;
  177.  
  178. # postprocess docnode
  179.  
  180.     # add a . to the end of the short if required.
  181.     my $short = $docNode->{ClassShort};
  182.  
  183.     if ( defined $short ) {
  184.         if ( !($short =~ /\.\s*$/) ) {
  185.             $docNode->{ClassShort} =~ s/\s*$/./;
  186.         }
  187.     }
  188.     else {
  189.         # use first line of normal text as short name.
  190.         if ( defined $docNode->{Text} ) {
  191.             my $node;
  192.             foreach $node ( @{$docNode->{Text}} ) {
  193.                 next if $node->{NodeType} ne "DocText";
  194.                 $short = $node->{astNodeName};
  195.                 $short = $`."." if $short =~ /\./;
  196.                 $docNode->{ClassShort} = $short;
  197.                 goto shortdone;
  198.             }
  199.         }
  200.     }
  201. shortdone:
  202.  
  203. # Join and break all word list props so that they are one string per list 
  204. # node, ie remove all commas and spaces.
  205.  
  206.     recombineOnWords( $docNode, "See" );
  207.     recombineOnWords( $docNode, "Throws" );
  208.  
  209.     return $docNode;
  210. }
  211.  
  212. =head3 setType
  213.  
  214.     Parameters: propname, proptype ( 0 = single, 1 = list, 2 = text )
  215.  
  216.     Set the name and type of the pending property.
  217.  
  218. =cut
  219.  
  220. sub setType
  221. {
  222.     ( $currentProp, $propType ) = @_;
  223. }
  224.  
  225. =head3 flushProp
  226.  
  227.     Flush any pending item and reset the buffer. type is set to DocText.
  228.  
  229. =cut
  230.  
  231. sub flushProp
  232. {
  233.     return if $buffer eq "";
  234.     initDocNode() unless defined $docNode;
  235.  
  236.     if( $propType == 1 ) {
  237.         # list prop
  238.         $docNode->AddPropList( $currentProp, $buffer );
  239.     }
  240.     elsif ( $propType == 2 ) {
  241.         # text prop
  242.         my $textnode = Ast::New( $buffer );
  243.         $textnode->AddProp( 'NodeType', $currentProp );
  244.         $docNode->AddPropList( 'Text', $textnode );
  245.         
  246.         foreach my $prop ( keys %extraprops ) {
  247.             $textnode->AddProp( $prop, 
  248.                 $extraprops{ $prop } );
  249.         }
  250.  
  251.         %extraprops = ();
  252.     }
  253.     else {
  254.         # one-off prop
  255.         $docNode->AddProp( $currentProp, $buffer );
  256.     }
  257.  
  258.     # reset buffer
  259.     $buffer = "";
  260.     setType( "DocText", 2 );
  261. }
  262.  
  263. =head3 codeProp
  264.  
  265.     Flush the last node, add a new property and reset type to DocText.
  266.  
  267. =cut
  268.  
  269. sub codeProp
  270. {
  271.     my( $prop, $val ) = @_;
  272.  
  273.     flushProp();
  274.  
  275.     initDocNode() unless defined $docNode;
  276.     $docNode->AddPropList( $prop, $val );
  277.     
  278.     setType( "DocText", 2 );
  279.  
  280. }
  281.  
  282. =head3 docListProp
  283.  
  284.     The next item is a list property of docNode.
  285.  
  286. =cut
  287.  
  288. sub docListProp
  289. {
  290.     my( $prop ) = @_;
  291.  
  292.     flushProp();
  293.  
  294.     $buffer = $';
  295.     setType( $prop, 1 );
  296. }
  297.  
  298. =head3 docProp
  299.  
  300.     The next item is a simple property of docNode.
  301.  
  302. =cut
  303.  
  304. sub docProp
  305. {
  306.     my( $prop ) = @_;
  307.     
  308.     flushProp();
  309.  
  310.     $buffer = $';
  311.     setType( $prop, 0 );
  312. }
  313.  
  314. =head3 textProp
  315.  
  316.     Parameters: prop, val
  317.  
  318.     Set next item to be a 'Text' list node. if val is assigned, the
  319.     new node is assigned that text and flushed immediately. If this
  320.     is the case, the next item is given the 'DocText' text property.
  321.  
  322. =cut
  323.  
  324. sub textProp
  325. {
  326.     my( $prop, $val ) = @_;
  327.  
  328.     flushProp();
  329.  
  330.     if ( defined $val ) {
  331.         $buffer = $val;
  332.         setType( $prop, 2 );
  333.         flushProp();
  334.         $prop = "DocText";
  335.     }
  336.  
  337.     setType( $prop, 2 );
  338.     $buffer = $';
  339. }
  340.  
  341.  
  342. =head3 initDocNode
  343.  
  344.     Creates docNode if it is not defined.
  345.  
  346. =cut
  347.  
  348. sub initDocNode
  349. {
  350.     $docNode = Ast::New( "Doc" );
  351.     $docNode->AddProp( "NodeType", "DocNode" );
  352. }
  353.  
  354. sub recombineOnWords
  355. {
  356.     my ( $docNode, $prop ) = @_;
  357.  
  358.     if ( exists $docNode->{$prop} ) {
  359.         my @oldsee = @{$docNode->{$prop}};
  360.         @{$docNode->{$prop}} = split (/[\s,]+/, join( " ", @oldsee ));
  361.     }
  362. }
  363.  
  364. ###############
  365.  
  366. =head2 attachDoc
  367.  
  368. Connects a docnode to a code node, setting any other properties
  369. if required, such as groups, internal/deprecated flags etc.
  370.  
  371. =cut
  372.  
  373. sub attachDoc
  374. {
  375.     my ( $node, $doc, $rootnode ) = @_;
  376.  
  377.     $node->AddProp( "DocNode", $doc );
  378.     $node->AddProp( "Internal", 1 ) if defined $doc->{Internal};
  379.     $node->AddProp( "Deprecated", 1 ) if defined $doc->{Deprecated};
  380.  
  381.     # attach group definitions if they exist
  382.     if ( defined $doc->{Groups} ) {
  383.         my $groupdef = $rootnode->{Groups};
  384.         if( !defined $groupdef ) {
  385.             $groupdef = Ast::New( "Groups" );
  386.             $rootnode->AddProp( "Groups", $groupdef );
  387.         }
  388.  
  389.         foreach my $grp ( @{$doc->{Groups}} ) {
  390.             if ( defined $groupdef->{ $grp->{astNodeName} } ) {
  391.                 $groupdef->{ $grp->{ astNodeName}
  392.                 }->AddProp( "Desc", $grp->{Desc} );
  393.             }
  394.             else {
  395.                 $groupdef->AddProp( $grp->{astNodeName}, $grp );
  396.             }
  397.         }
  398.     }
  399.  
  400.     # attach node to group index(es)
  401.     # create groups if not found, they may be parsed later.
  402.  
  403.     if ( defined $doc->{InGroup} ) {
  404.         my $groupdef = $rootnode->{Groups};
  405.  
  406.         foreach my $grp ( @{$doc->{InGroup}} ) {
  407.             if ( !exists $groupdef->{$grp} ) {
  408.                 my $newgrp = Ast::New( $grp );
  409.                 $newgrp->AddProp( "Desc", $grp );
  410.                 $newgrp->AddProp( "NodeType", "GroupDef" );
  411.                 $groupdef->AddProp( $grp, $newgrp );
  412.             }
  413.  
  414.             $groupdef->{$grp}->AddPropList( "Kids", $node );
  415.         }
  416.     }
  417. }
  418.  
  419. 1;
  420.